﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace comtnet
{
    public partial class Form1 : Form
    {
        SerialPort sp = null;
        Client ct = new Client();
        private string net_ip;
        private int net_port;

        public Form1()
        {
            InitializeComponent();
        }

        private void comboBox_com_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        /// <summary>
        /// 串口初始化
        /// </summary>
        /// <returns></returns>
        private SerialPort serialPort_Init()
        {
            SerialPort sp = null;
            try
            {
                sp = new SerialPort();
                sp.PortName = comboBox_com.Text.Trim();
                sp.BaudRate = Convert.ToInt32(comboBox_baute.Text.Trim());
                sp.DataBits = 8;
                sp.Parity = Parity.None;
                sp.StopBits = StopBits.One;
                sp.DataReceived += Sp_DataReceived;
            }
            catch (System.Exception ex)
            {
                throw ex;
            }

            return sp;
        }

        private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                byte[] rdata = new byte[sp.BytesToRead];
                sp.Read(rdata,0,rdata.Length);
                write_com_auto_text("rev>",rdata);
                //向网络端发数据
                if(internetOnline!=false)
                {
                    write_net_auto_text("send>",rdata);
                    socket_write_device_data(rdata);
                }

            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private delegate void dele_write_text(string str);
        /// <summary>
        /// 将字符串写入串口日志框内
        /// </summary>
        /// <param name="headstr"></param>
        /// <param name="stn"></param>
        private void write_com_auto_text(string headstr,byte[] stn)
        {
                string headtime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:ffff");
                string stn_str = "";
                StringBuilder sb = new StringBuilder();
                for (int a = 0; a < stn.Length; a++)
                {
                    sb.Append(stn[a].ToString("X2"));
                    sb.Append(" ");
                }

                stn_str = sb.ToString();

                string writeline = "[" + headtime + "]" + headstr + " " + stn_str + "\r\n";
                
                TextDisplay td = new TextDisplay();
                 
                td.displayStr = writeline;

                td.textbox = textBox_comauto;

                if (headstr.IndexOf('>')>-1)
                {
                    td.backColor = Color.WhiteSmoke;
                }
                delt_text_display(td);
        }
        /// <summary>
        /// 将字符串写入网络日志框内
        /// </summary>
        /// <param name="headstr"></param>
        /// <param name="stn"></param>
        private void write_net_auto_text(string headstr, byte[] stn)
        {
            string headtime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:ffff");

            string stn_str = "";

            StringBuilder sb = new StringBuilder();
            for (int a = 0; a < stn.Length; a++)
            {
                sb.Append(stn[a].ToString("X2"));
                sb.Append(" ");
            }

            stn_str = sb.ToString();

            string writeline = "[" + headtime + "]" + headstr + " " + stn_str + "\r\n";

            TextDisplay td = new TextDisplay();

            td.displayStr = writeline;

            td.textbox = text_netauto;

            if (headstr.IndexOf('>') > -1)
            {
                td.backColor = Color.WhiteSmoke;
            }
            delt_text_display(td);

        }

        private delegate void delte_write_text(TextDisplay td);
       /// <summary>
       /// 委托文本框打印字符串
       /// </summary>
       /// <param name="td"></param>
        private void delt_text_display(TextDisplay td)
        {
            if (this.InvokeRequired != false)
            {
                delte_write_text dwt = new delte_write_text(delt_text_display);
                this.Invoke(dwt, td);
            }
            else
            {
                td.textbox.AppendText(td.displayStr);
                td.textbox.Select(td.textbox.Text.Length + 1 - td.displayStr.Length, td.textbox.Text.Length);
                td.textbox.SelectionBackColor = td.backColor;
                td.textbox.ScrollToCaret();
            }
        }

        private void button_com_Click(object sender, EventArgs e)
        {
            try
            {
                if (button_com.Text.Trim() == "打开")
                {
                    sp = serialPort_Init();
                    sp.Open();
                    button_com.Text = "关闭";
                    comboBox_com.Enabled = false;
                    comboBox_baute.Enabled = false;
                }
                else
                {
                    button_com.Text = "打开";
                    comboBox_com.Enabled = true;
                    comboBox_baute.Enabled = true;
                    sp.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();
            comboBox_com.Items.Clear();
            foreach (string st in ports)
            {
                comboBox_com.Items.Add(st);
            }
            if (ports.Length != 0) comboBox_com.SelectedIndex = 0;
        }

        private void comboBox_com_Click(object sender, EventArgs e)
        {
            string[] ports = System.IO.Ports.SerialPort.GetPortNames();
            comboBox_com.Items.Clear();
            foreach (string st in ports)
            {
                comboBox_com.Items.Add(st);
            }
        }
        #region "网络连接"
        private Client cst;
        private delegate void internet_status_set_delegate(Boolean fs);
        private Boolean internetOnline = false;
        private System.Threading.Thread internetInitThread;
        private void socket_close()
        {
            try
            {
                cst.socket_close();
                internet_stauts_set(false);


            }
            catch (System.Exception ex)
            {
                //log lg = new log();
                //lg.log_write("断开网络出错");
            }
        }
        private void internet_stauts_set(Boolean fs)
        {
            //TextDisplay td = new TextDisplay();
            if (this.InvokeRequired != false)
            {
                internet_status_set_delegate id = new internet_status_set_delegate(internet_stauts_set);
                this.Invoke(id, fs);
            }
            else
            {
                internetOnline = fs;
                if (fs == false)
                {
                    button_netopen.Text = "连接";
                    textBox_ip.Enabled = true;
                    textBox_port.Enabled = true;
                    //log lg = new log();
                    //lg.log_write("ID:" + device_id + "->" + "断开服务器");
                    //td.textbox = text_netauto;
                    //td.backColor = Color.WhiteSmoke;
                    //td.displayStr = "^~^:服务器断开\r\n";
                    //delt_text_display(td);
                }
                else
                {
                    button_netopen.Text = "断开";
                    textBox_ip.Enabled = false;
                    textBox_port.Enabled = false;
                //    td.textbox = text_netauto;
                //    td.backColor = Color.WhiteSmoke;
                //    td.displayStr = "^~^:服务器连接\r\n";
                //    delt_text_display(td);
                 }

            }
        }
        public void socket_tcp_init()
        {
            internet_stauts_set(false);

            internetInitThread = new System.Threading.Thread(socket_tcp_init_thread);
            internetInitThread.Start();
        }
        private void socket_tcp_init_thread()
        {
            try
            {
                if (internetOnline == false)
                {
                    cst = new Client(socket_rev_deal);
                    cst.client_config(net_ip, net_port);
                    cst.netOnlineStatus = new Client.internetOnlineStatusDelegate(internet_stauts_set);//在线检测
                    System.Threading.Thread td = new System.Threading.Thread(socket_connect_thead);
                    td.Start();
                    System.Threading.Thread.Sleep(5000);
                }
            }
            catch (System.Exception ex)
            {
                //log lg = new log();
                //lg.log_write("网络连接失败");
            }

        }

        private void socket_connect_thead()
        {
            try
            {
                if (cst.socket_link())
                {
                    //连上网络
                }
            }
            catch (System.Exception ex)
            {
            }
        }
        /// <summary>
        /// tcp socket发数据
        /// </summary>
        /// <param name="data"></param>
        private void socket_write_device_data(byte[] data)
        {
            try
            {
                cst.socket_send_data(data);

            }catch(Exception ex)
            {
                internet_stauts_set(false);
            }
        }

        /// <summary>
        /// 接收服务器数据处理
        /// </summary>
        /// <param name="bdata"></param>
        private void socket_rev_deal(byte[] bdata)
        {
            write_net_auto_text("rev<",bdata);
            if (sp == null) return;
            if (sp.IsOpen == false) return;
            write_com_auto_text("send<",bdata);
            sp.Write(bdata,0,bdata.Length);
        }
        #endregion

        private void button_netopen_Click(object sender, EventArgs e)
        {
            try
            {
                if(button_netopen.Text.Trim()=="断开")
                {
                    socket_close();
                }
                else
                {
                    net_ip = textBox_ip.Text.Trim();
                    net_port = Convert.ToInt32(textBox_port.Text.Trim());
                    ct.client_config(net_ip, net_port);
                    socket_tcp_init();
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            textBox_comauto.Text = "";
        }

        private void button_clearcom_Click(object sender, EventArgs e)
        {
            textBox_comauto.Text = "";
        }

        private void button_clearnet_Click(object sender, EventArgs e)
        {
            text_netauto.Text = "";
        }
        private const string PATTERN = @"([^A-Fa-f0-9]|\s+?)+";
        /// <summary>
        /// 检查字符串是否合法
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private bool check_string_is_hex(string str)
        {
            string tstr = str.Trim();
            if (tstr.Trim().Length < 1)
            {
                MessageBox.Show("输入不能为空");
                return false;
            }
            tstr= tstr.Replace(" ","");
            if(tstr.Length%2!=0)
            {
                MessageBox.Show("输入字符串数量不为偶数");
                return false;
            }
            if( System.Text.RegularExpressions.Regex.IsMatch(tstr, PATTERN)!=false)
            {
                MessageBox.Show("输入字符串不合法");
                return false;
            }
            return true;
        }
        /// <summary>
        /// 将字符串转换为byte
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private byte[] turn_asiic_to_hex(string str)
        {

            //去空格
            str = str.Replace(" ", "");
            byte[] tb = new byte[str.Length/2];

            for(int i=0;i<tb.Length;i++)
            {
                tb[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);
            }
            return tb;
        }
        /// <summary>
        /// 手动向串口HEX发数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_comhandsend_Click(object sender, EventArgs e)
        {
            if(check_string_is_hex(textBox_comhandsend.Text)==false)
            {
                return;
            }
            if(sp.IsOpen==false)
            {
                MessageBox.Show("串口未打开");
                return;
            }
            try
            {
                byte[] sdata = turn_asiic_to_hex(textBox_comhandsend.Text);
                sp.Write(sdata,0,sdata.Length);
                write_com_auto_text("Hsend<",sdata);
            }catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void button_handnetsend_Click(object sender, EventArgs e)
        {
            if (check_string_is_hex(textBox_handnetsend.Text) == false)
            {
                return;
            }
            if (internetOnline == false)
            {
                MessageBox.Show("服务器未连接");
                return;
            }
            try 
            {
                byte[] sdata = turn_asiic_to_hex(textBox_handnetsend.Text);
                socket_write_device_data(sdata);
                write_net_auto_text("Hsend>", sdata);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            Size ts = this.Size;

            groupBox_com.Location = new Point(5,10);
            groupBox_com.Size = new Size(this.Size.Width/2-20,this.Size.Height-50);

            groupBox_net.Location = new Point(this.Size.Width/2,10);
            groupBox_net.Size = new Size(this.Size.Width/2-20,this.Size.Height-50);
        }

        private void Form1_ResizeEnd(object sender, EventArgs e)
        {
          //  MessageBox.Show("调整大小完成");
        }
    }
}
